<template>
  <div class="container">
    <div>
      <label>输入：<input type="text" class="input" v-model="question"></label>
      <button @click="update">提交</button>
    </div>
    <div class="output">
      <div>
        <label>Streaming</label><input type="checkbox" v-model="stream">
      </div>
      <div>{{content}}</div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
const question = ref('讲一个十二生肖的故事')
const content = ref('')
const stream = ref(false)

const update = async () => {
  if (!question.value) return
  content.value = '思考中...'

  const endpoint = 'https://api.deepseek.com/chat/completions'
  const headers = {
    "Content-Type": "application/json",
    "Authorization": "Bearer " + import.meta.env.VITE_DEEPSEEK_API_KEY
  }
  const response = await fetch(endpoint, {
    method: "POST",
    headers,
    body: JSON.stringify({
      model: 'deepseek-chat',
      messages: [{ role: 'user', content: question.value }],
      stream: stream.value,
    })
  })

  if (stream.value) {
    const reader = response.body?.getReader() // 因为response.body是ReadableStream，所以可以使用getReader()方法获取一个ReadableStreamDefaultReader对象
    const decoder = new TextDecoder() // 对二进制数据进行解码
    let done = false  // 标记是否读取完成
    let buffer = ''
    while (!done) {
      const { value, done:doneReading } = await reader?.read()
      done = doneReading
      const chunkValue = buffer + decoder.decode(value)
      buffer = ''
      const lines = chunkValue.split('\n').filter(line => line.startsWith('data: '))
      
      for (const line of lines) { // 逐行处理
        const incoming = line.slice(6)
        console.log(incoming);
        
        if (incoming === '[DONE]') {
          done = true
          break
        }
        try {
          const data = JSON.parse(incoming)
          const delta = data.choices[0].delta.content
          if (delta) {
            content.value += delta
          }
        } catch (error) {
          buffer += incoming
        }
      }

    }
  } else {
    const data = await response.json()
    content.value = data.choices[0].message.content
  }

}
</script>

<style scoped>
.container{
  display: flex;
  flex-direction: column;
  align-items: start;
  justify-content: start;
  height: 100vh;
  font-size: 0.85rem;
}
.input{
  width: 200px;
}
.output{
  margin-top: 10px;
  min-height: 300px;
  width: 100%;
  text-align: left;
}
button{
  padding: 0 10px;
  margin-left: 6px;
}
</style>